package com.yum.Iterator.List.Vector;

import com.yum.Iterator.Arrays.YArrays;
import com.yum.Iterator.Collection.YCollection;
import com.yum.Iterator.List.YAbstractList.YAbstractList;
import com.yum.Iterator.List.YArrayList.YArrayList;
import com.yum.Iterator.List.YList;

import java.lang.Object;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Iterator;
import java.util.RandomAccess;
import java.util.Vector;

/**
 * Vector是个动态数组 于ArrayList相似 Vector是同步访问的，线程安全
 * @param <E>
 */
public class YVector<E> extends YAbstractList<E> implements YList<E>,
        RandomAccess, Serializable,Cloneable {

    private static final long serialVersionUID = 1671282573068673907L;

    protected Object[] eleData;

    protected int eleCount;

    /**
     * 动态增长因子
     * 于ArrayList的最大区别 ArrayList每次增长为原长度的1.5倍
     * 若capacityIncrement为0时，向量按2倍容量的方式扩容
     * 当不为0时，向量按照此参数固定扩容
     */
    protected int capacityIncrement;


    public YVector() {
        this(10);

    }

    public YVector(int count, int capacityIncrement) {
        if(count < 0 || capacityIncrement < 0){
            throw new IllegalArgumentException("长度错误");
        }
        this.eleData = new Object[count];
        this.capacityIncrement = capacityIncrement;
    }

    public YVector(int count) {
        this(count,0);
    }

    public YVector(YCollection<? extends E> Yc){
        Object[] a = Yc.toArray();
        eleCount = a.length;
        eleData = Yc.getClass() == YArrayList.class ? a : YArrays.copyOf(a,eleCount,Object[].class);
    }

    @Override
    public int size() {
        return eleData.length;
    }

    @Override
    public E getValue(int index) {
        return super.getValue(index);
    }

    @Override
    public synchronized boolean setValue(int index, E value) {
        return super.setValue(index, value);
    }

    @Override
    public synchronized boolean add(E e) {
        modCount++;
        checkCapacity(eleCount + 1);
        eleData[eleCount++] = e;
        return true;
    }

    @Override
    public synchronized boolean addAll(YCollection<? extends E> Yc) {
        return super.addAll(Yc);
    }

    @Override
    public synchronized void clear() {
        super.clear();
    }

    @Override
    public boolean contains(Object o) {
        return super.contains(o);
    }

    @Override
    public boolean contatinsAll(YCollection<?> Yc) {
        return super.contatinsAll(Yc);
    }

    @Override
    public boolean isEmpty() {
        return size() == 0;
    }

    @Override
    public synchronized boolean remove(Object o) {
        return super.remove(o);
    }

    @Override
    public synchronized boolean removeAll(YCollection<?> Yc) {
        return super.removeAll(Yc);
    }

    public synchronized void removeElement(int index){
        modCount++;
        if(index > eleCount){
            throw new IllegalArgumentException("长度错误");
        }
        else if(index < 0){
            throw new ArrayIndexOutOfBoundsException(index);
        }
        eleCount--;
        eleData[eleCount] = null;
    }

    public synchronized E elementAt(int index){
        return (E) eleData[index];
    }

    @Override
    public E[] toArray(E[] a) {
        return super.toArray(a);
    }

    @Override
    public E[] toArray() {
        return super.toArray();
    }

    @Override
    public Object clone() {
        return super.clone();
    }

    @Override
    public int indexOf(Object value) {
        if(value == null){
            for(int i=0;i<eleCount;i++){
                if(eleData[i] == null){
                    return i;
                }
            }
        }
        else{
            for (int i=0;i<eleCount;i++){
                if(eleData[i].equals(value)){
                    return i;
                }
            }
        }
        return -1;
    }

    @Override
    public int lastIndexOf(Object value) {
        return super.lastIndexOf(value);
    }

    @Override
    public Iterator<E> iterator() {
        return super.iterator();
    }

    private void checkCapacity(int minCapacity){
        if((minCapacity - eleData.length) > 0){
            expand(minCapacity);
        }
    }


    /**
     * 动态增长
     * @param minCapacity 最小容量
     */
    private void expand(int minCapacity){
        int oldCapacity = eleData.length;
        //若设置了capacityIncrement 则为旧长度加capacityIncrement 若未设置则为旧长度的两倍
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement:oldCapacity);
        if(newCapacity - minCapacity < 0){
            newCapacity = minCapacity;
        }
        eleData = YArrays.copyOf(eleData,newCapacity);
    }
}
